/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Seoprofesional
 *
 * The Initial Developer of the Original Code is
 * Petr Blahoš.
 * Portions created by the Initial Developer are Copyright (C) 2009
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */



var sbView = {
link_comparator: {
	nofollow: function(domain, x)	{ 	return -1!=x.rel.toLowerCase().indexOf("nofollow"); },
	all: function(domain, x)	{	return true;				},
	internal: function(domain, x) 	{	return SeoprofesionalTools.get_domain(x.href)==domain;		},
	external: function(domain, x) 	{	return !sbView.link_comparator.internal(domain, x);	},
	_x_sentinel_0: 0
},
whitelist : [],
visibleData: [],
init: function() {
	this.browser = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
	   .getInterface(Components.interfaces.nsIWebNavigation)
	   .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
	   .rootTreeItem
	   .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
	   .getInterface(Components.interfaces.nsIDOMWindow).gBrowser;

	this.strings = document.getElementById("seop-strings");
	this.whitelist = sbView.seopdb.get_whitelist();
	this.visibleData = [];
	this.hllist = document.getElementById("hllist");
	this.hlsplitter = document.getElementById("hlsplitter");
	for (var i = 0;i<this.whitelist.length;i++) {
		this.visibleData.push([ this.whitelist[i], true, false ]);
	}
},

treeBox: null,  
selection: null,  

get rowCount()                     { return this.visibleData.length; },  
setTree: function(treeBox)         { this.treeBox = treeBox; },  
getCellText: function(idx, column) {
	if (this.isContainer(idx)) {
		if ("url"==column.id)		return this.visibleData[idx][0];
		return "1";
	}
	var par = this.getParentIndex(idx);
	var root = this.visibleData[par][0];
	if ("url"==column.id) {
		var ret = this.visibleData[idx][0].substring(this.visibleData[par][0].length);
		if (0==ret.length)	return "."
		return ret;
	}
	return "2";
},  
isContainer: function(idx)         { return sbView.visibleData[idx][1]; },  
isContainerOpen: function(idx)     { return this.visibleData[idx][2]; },  
isContainerEmpty: function(idx)    { return false; },  
isSeparator: function(idx)         { return false; },  
isSorted: function()               { return false; },  
isEditable: function(idx, column)  { return false; },  

getParentIndex: function(idx) {  
	if (this.isContainer(idx)) return -1;  
	for (var t = idx - 1; t >= 0 ; t--) {  
		if (this.isContainer(t)) return t;  
	}  
},  
getLevel: function(idx) {  
	if (this.isContainer(idx)) return 0;  
	return 1;  
},  
hasNextSibling: function(idx, after) {
	var thisLevel = this.getLevel(idx);  
	for (var t = after + 1; t < this.visibleData.length; t++) {  
		var nextLevel = this.getLevel(t);  
		if (nextLevel == thisLevel) return true;  
		if (nextLevel < thisLevel) break;  
	}  
	return false;  
},
toggleOpenState: function(idx) {
	var item = this.visibleData[idx];  
	if (!item[1]) return;  

	if (item[2]) {
		item[2] = false;  

		var thisLevel = this.getLevel(idx);  
		var deletecount = 0;  
		for (var t = idx + 1; t < this.visibleData.length; t++) {  
			if (this.getLevel(t) > thisLevel) deletecount++;  
			else break;  
		}  
		if (deletecount) {  
			this.visibleData.splice(idx + 1, deletecount);  
			this.treeBox.rowCountChanged(idx + 1, -deletecount);  
		}  
	}  
	else {  
		item[2] = true;  

		var root = this.visibleData[idx][0];  
		var toinsert = sbView.seopdb.get_sub(root);
		for (var i = 0; i < toinsert.length; i++) {  
			this.visibleData.splice(idx + i + 1, 0, [toinsert[i], false]);  
		}  
		this.treeBox.rowCountChanged(idx + 1, toinsert.length);  
	}
	this.treeBox.invalidateRow(idx);  
},  

getImageSrc: function(idx, column) {
	var url = this.visibleData[idx][0];
	var iconURL = "chrome://browser/skin/Bookmarks-folder.png";
	try {
		var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
		var historyService = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);

		var options = historyService.getNewQueryOptions();
		var query = historyService.getNewQuery();

		options.resultType = options.RESULTS_AS_URI;
		query.uri = ioService.newURI(url, null, null);

		var result = historyService.executeQuery(query, options);
		result.root.containerOpen = true;
		try {
			// if it fails here, we need to close the container
			iconURL = result.root.getChild(0).icon.spec;
		} catch (e) {
		}
		result.root.containerOpen = false;
	} catch (e) {
	}
	return iconURL;
},
getProgressMode : function(idx,column) {},
getCellValue: function(idx, column) {},
cycleHeader: function(col, elem) {},
selectionChanged: function() {},
cycleCell: function(idx, column) {},
performAction: function(action) {},
performActionOnCell: function(action, index, column) {},
getRowProperties: function(idx, column, prop) {},
getCellProperties: function(idx, column, prop) {},
getColumnProperties: function(column, element, prop) {},

click: function(tree, ev) {
	if (2==ev.button) {
		return ;
	}
	var tbo = tree.treeBoxObject;
	var row = { }, col = { }, obj = { };
	tbo.getCellAt(ev.clientX, ev.clientY, row, col, obj);
	if (-1==row.value) {
		return ;
	}
	if (this.isContainer(row.value)) {
		return ;
	}
	this.browser.openUILink(this.visibleData[row.value][0], ev, false, true);
},
counter: 0,
tt_uri: "",
tipShowing: function(ev) {
	var tbo = document.getElementById("seop-uri-tree").treeBoxObject;
	var row = { }, col = { }, obj = { };
	tbo.getCellAt(ev.clientX, ev.clientY, row, col, obj);
	if (-1==row.value) {
		return false;
	}
	this.tt_uri = this.visibleData[row.value][0];
	if (!sbView.seopdb.is_whitelisted(this.tt_uri)) {
		return false;
	}
	return true;
},
tipShown: function(ev) {
	SeoprofesionalTools.set_attr("seop-tip-footer", "value", sbView.tt_uri);
	SeoprofesionalTools.set_attr("seop-tip-frame", "src", "chrome://seoprofesional/content/plot.html?" + this.counter++ + "&uri=" + sbView.tt_uri);
	return true;
},
prepare_menu: function(ev) {
	var row = document.getElementById("seop-uri-tree").currentIndex;
	if (-1==row) {
		return false;
	}
	if (sbView.isContainer(row)) {
		SeoprofesionalTools.set_attr("st-forget", "hidden", true);
	} else {
		SeoprofesionalTools.set_attr("st-forget", "hidden", false);
	}
	return true;
},
forget: function(ev) {
	var row = document.getElementById("seop-uri-tree").currentIndex;
	if (-1==row) {
		return ;
	}
	var uri = sbView.visibleData[row][0];
	sbView.seopdb.forget_record(uri);
	row = sbView.getParentIndex(row);
	sbView.toggleOpenState(row);
	sbView.toggleOpenState(row);
},
refresh: function(ev) {
	var row = document.getElementById("seop-uri-tree").currentIndex;
	if (-1==row) {
		return ;
	}
	var uri = sbView.visibleData[row][0];
	if (sbView.isContainer(row)) {
		var uris = sbView.seopdb.get_sub(uri);
		for (var j = 0; j < uris.length; j++) {  
			for (var i = 0;i<sbView.seop_global.fetchers.length;i++) {
				var f = sbView.seop_global.fetchers[i];
				if (f.enabled) {
					sbView.seop_global.fetchers[i].fetch(null, uris[j]);
				}
			}
		}
		return;
	}
	for (var i = 0;i<sbView.seop_global.fetchers.length;i++) {
		var f = sbView.seop_global.fetchers[i];
		if (f.enabled) {
			sbView.seop_global.fetchers[i].fetch(null, uri);
		}
	}
	
},
unhilight_all: function() {
	for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
		try {
			sbView.unhilight_win(sbView.browser.contentWindow.frames[i], Ci.nsISelectionController.SELECTION_FIND);
		} catch (e) {
			SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
		}
	}
	try {
		sbView.unhilight_win(sbView.browser.contentWindow, Ci.nsISelectionController.SELECTION_FIND);
	} catch (e) {
		SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
	}
	sbView.hllist.setAttribute("hidden", true);
	sbView.hlsplitter.setAttribute("hidden", true);
},
unhilight_win: function(win, type) {
        var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebNavigation)
                                .QueryInterface(Ci.nsIDocShell);

        var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsISelectionDisplay)
                                   .QueryInterface(Ci.nsISelectionController);
	var find_selection = controller.getSelection(type);
	find_selection.removeAllRanges();
},
set_hllist: function(items) {
	while(null!=sbView.hllist.firstChild) {
		sbView.hllist.removeChild(sbView.hllist.firstChild);
	}
	for (var i = 0;i<items.length; i++) {
		var item = document.createElement("listitem");
		item.setAttribute("label", "" + (1+i) + ": " + items[i][0]);
		item.setAttribute("index", i);
		sbView.hllist.appendChild(item);
	}
	sbView.hl_ranges = items;
	sbView.hllist.setAttribute("hidden", false);
	sbView.hlsplitter.setAttribute("hidden", false);
},
hllist_sel: function(el, ev) {
	var si = el.selectedItem;
	if (null==si) {
		return ;
	}
	for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
		try {
			sbView.unhilight_win(sbView.browser.contentWindow.frames[i], Ci.nsISelectionController.SELECTION_NORMAL);
		} catch (e) {
			SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
		}
	}
	try {
		sbView.unhilight_win(sbView.browser.contentWindow, Ci.nsISelectionController.SELECTION_NORMAL);
	} catch (e) {
		SeoprofesionalTools.LOG("win:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
	}

	var i = 1*si.getAttribute("index");
	var item = sbView.hl_ranges[i];

	item[2].getSelection(Ci.nsISelectionController.SELECTION_NORMAL).addRange(item[1]);
	item[2].scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL, Ci.nsISelectionController.SELECTION_ANCHOR_REGION, false);
},
hilight_links: function () {
	var input = document.getElementById("hllink").value;
	var include = sbView.link_comparator[input];
	var refs = [];
	for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
		try {
			sbView.hilight_links_doc(refs, include, sbView.browser.contentWindow.frames[i]);
		} catch (e) {
			SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
		}
	}
	try {
		sbView.hilight_links_doc(refs, include, sbView.browser.contentWindow);
	} catch (e) {
		SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
	}
	sbView.set_hllist(refs);
},
hilight_links_doc: function(refs, include, win) {
	var doc = win.document;
	if (!doc || !(doc instanceof HTMLDocument)) {
		return ;
	}
        var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebNavigation)
                                .QueryInterface(Ci.nsIDocShell);

        var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsISelectionDisplay)
                                   .QueryInterface(Ci.nsISelectionController);
	var find_selection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);

	find_selection.removeAllRanges();

	var domain = SeoprofesionalTools.get_domain(doc.baseURIObject.spec);
	for (var i = 0; i<doc.links.length;i++) {
		if (include(domain, doc.links[i])) {
			var range = doc.createRange();
			try {
				range.setStart(doc.links[i], 0);
				range.setEnd(doc.links[i], 1);
				find_selection.addRange(range);
				refs.push([ doc.links[i].href, range, controller ]);
			} catch (e) {
				SeoprofesionalTools.LOG("==> range error!!!:" + range);
			}
		}
	}
	controller.setDisplaySelection(Ci.nsISelectionController.SELECTION_ON);
},
hilight_kw: function() {
	var input = document.getElementById("hlkw").value;
	var refs = [];
	for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
		try {
			sbView.hilight_kw_doc(refs, input, sbView.browser.contentWindow.frames[i]);
		} catch (e) {
			SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
		}
	}
	try {
		sbView.hilight_kw_doc(refs, input, sbView.browser.contentWindow);
	} catch (e) {
		SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
	}
	sbView.set_hllist(refs);
},
hilight_kw_doc: function(refs, input, win) {
	var doc = win.document;
	if (!doc || !(doc instanceof HTMLDocument)) {
		return ;
	}
	var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
				.getInterface(Ci.nsIWebNavigation)
				.QueryInterface(Ci.nsIDocShell);
	var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
				   .getInterface(Ci.nsISelectionDisplay)
				   .QueryInterface(Ci.nsISelectionController);
	var find_selection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);

	find_selection.removeAllRanges();
	if (""==input) {
		return;
	}
	var body = doc.body;
	var count = body.childNodes.length;
	var searchRange = doc.createRange();
	var startPt = doc.createRange();
	var endPt = doc.createRange();

	searchRange.setStart(body, 0);
	searchRange.setEnd(body, count);

	startPt.setStart(body, 0);
	startPt.setEnd(body, 0);
	endPt.setStart(body, count);
	endPt.setEnd(body, count);

	var retRange = null;
	var finder = Cc["@mozilla.org/embedcomp/rangefind;1"].createInstance().QueryInterface(Ci.nsIFind);
	finder.caseSensitive = false;

	while((retRange = finder.Find(input, searchRange, startPt, endPt))) {
		startPt = retRange.endContainer.ownerDocument.createRange();
		startPt.setStart(retRange.endContainer, retRange.endOffset);
		startPt.setEnd(retRange.endContainer, retRange.endOffset);

		find_selection.addRange(retRange);
		r2 = retRange.cloneRange();
		if (r2.startOffset>5) {
			r2.setStart(r2.startContainer, r2.startOffset-5);
		} else {
			r2.setStart(r2.startContainer, 0);
		}
		r2.setEndAfter(r2.endContainer);
		refs.push([ "..." + r2 + "...", retRange, controller ]);
	}
	controller.setDisplaySelection(Ci.nsISelectionController.SELECTION_ON);
},
_x_sentinel_0: 0
};  

Components.utils.import("resource://seoprofesional/seopdb.jsm", sbView);

window.addEventListener("load", function(e) { 
    sbView.init();
    document.getElementById('seop-uri-tree').view = sbView;
}, false);


